package com.huatai.bi.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.huatai.bi.entity.DataProcessEntity;
import com.huatai.bi.entity.DataSetColumnEntity;
import com.huatai.bi.service.DataProcessService;
import com.huatai.bi.service.DataSetColumnService;
import com.huatai.bi.service.OpenApiService;
import com.huatai.bi.utils.APIQueryUtil;
import com.huatai.bi.utils.StringBuildUtil;
import com.huatai.bi.vo.bigScreenVO.ApiPageDataVO;
import com.huatai.bi.vo.excelVo.HeardVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @BelongsProject: itc-airport-cloud
 * @BelongsPackage: com.itc.bi.service.impl
 * @Author: hecaiy
 * @CreateTime: 2024-07-23  14:06
 * @Description: TODO 开放接口实现层
 * @Version: 1.0
 */
@Service
public class OpenApiServiceImpl implements OpenApiService {

    @Autowired
    private DataProcessService dataProcessService;
    @Autowired
    private ClickHouseJDBCService clickHouseJDBCService;
    @Autowired
    private DataSetColumnService dataSetColumnService;

    /**
     * 获取数据
     * @param processId 数据加工标识
     * @param params     查询参数 包括分页、过滤条件等参数
     * @return
     */
    @Override
    public ApiPageDataVO query(String processId, Map<String,Object> params) {
        DataProcessEntity dataProcessEntity = dataProcessService.getById(processId);
        if(ObjectUtil.isEmpty(dataProcessEntity) || dataProcessEntity.getType().equalsIgnoreCase("aggregate")){
            throw new RuntimeException("数据加工标识不存在!!!请确认加工标识数据");
        }
        //每页大小最大值为
        int pageSize = dataProcessEntity.getPageSize();
        Object pageSizeObj = params.get("pageSize");
        if(ObjectUtil.isNotEmpty(pageSizeObj)){
            pageSize = Integer.parseInt(pageSizeObj.toString())>=pageSize?pageSize:Integer.parseInt(pageSizeObj.toString());
        }
        int pageIndex = 1;
        Object pageIndexObj = params.get("pageIndex");
        if(ObjectUtil.isNotEmpty(pageIndexObj)){
            pageIndex = Integer.parseInt(pageIndexObj.toString())<=0?1:Integer.parseInt(pageIndexObj.toString());
        }
        StringBuilder sqlBuilder = new StringBuilder();
        if(ObjectUtil.isNotEmpty(params)){
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                String whereSql = APIQueryUtil.querySQLStr(entry.getKey(), entry.getValue());
                if(ObjectUtil.isNotEmpty(whereSql) && !whereSql.equals(" ")){
                    sqlBuilder.append(whereSql).append(" and ");
                }
            }
            StringBuildUtil.deleteSBWithSpace(sqlBuilder,"a",4);
        }
        String whereSql = "";
        if(sqlBuilder.length()>0){
            whereSql = " where "+sqlBuilder.toString();
        }

        ApiPageDataVO apiPageDataVO = new ApiPageDataVO();
        List<HeardVO> columns = new ArrayList<>();

        List<String> limitColumns = new ArrayList<>();
        String groupBySql="";
        if(ObjectUtil.isNotEmpty(params)){
            Object orDefault = params.getOrDefault("groupBy", "");
            if(ObjectUtil.isNotEmpty(orDefault)){
                groupBySql = orDefault.toString();
                limitColumns.addAll(Arrays.asList(groupBySql.split(",")));
            }
        }

        List<DataSetColumnEntity> dataSetColumnEntities = dataSetColumnService.columnListById(dataProcessEntity.getId());
        if(dataSetColumnEntities!=null && dataSetColumnEntities.size()>0) {
            for (DataSetColumnEntity dataSetColumnEntity : dataSetColumnEntities){
                if(limitColumns!=null && limitColumns.size()>0){
                    if(limitColumns.contains(dataSetColumnEntity.getColumnName())){
                        columns.add(new HeardVO(dataSetColumnEntity.getColumnName(),dataSetColumnEntity.getColumnComment(),dataSetColumnEntity.getColumnType()));
                    }
                }else {
                    columns.add(new HeardVO(dataSetColumnEntity.getColumnName(),dataSetColumnEntity.getColumnComment(),dataSetColumnEntity.getColumnType()));
                }
            }
        }
        List<String> collect = columns.stream().map(p -> p.getKey()).distinct().collect(Collectors.toList());
        String columnsStr = StringUtils.join(collect,",");

        String groupBy = "";
        if(groupBySql.length()>0){
            groupBySql = "`" +groupBySql.replace(",","`,`")+"`";
            groupBy = " group by "+groupBySql.toString();
            columnsStr = groupBySql;
        }else{
            columnsStr = "`"+columnsStr.replace(",","`,`")+"`";
        }

        if(pageIndex<=0){
            pageIndex = 1;
        }
        if(pageSize<=0){
            pageSize = 10;
        }

        String sql = "select "+columnsStr+" from "+dataProcessEntity.getTableName() + whereSql+groupBy +" limit "+(pageIndex-1)*pageSize+","+pageSize;
        List<LinkedHashMap<String, Object>> linkedHashMaps = clickHouseJDBCService.queryTableBySqlNotRemove(sql);
        apiPageDataVO.setColumns(columns);
        apiPageDataVO.setDataList(linkedHashMaps);
        apiPageDataVO.setPageIndex(pageIndex);
        apiPageDataVO.setPageSize(pageSize);
        apiPageDataVO.setTotal(clickHouseJDBCService.getTableSizeSql(sql.substring(0,sql.lastIndexOf("limit"))));
        return apiPageDataVO;
    }

    /**
     * 获取数据集数据项
     * @param processId
     * @return
     */
    @Override
    public List<HeardVO> getDataSetColumnsList(Long processId){
        DataProcessEntity dataProcessEntity = dataProcessService.getById(processId);
        //聚合指标
        if(ObjectUtil.isEmpty(dataProcessEntity) || dataProcessEntity.getType().equalsIgnoreCase("aggregate")){
            throw new RuntimeException("数据加工标识不存在!!!请确认加工标识数据");
        }
        List<HeardVO> columns = new ArrayList<>();
        List<DataSetColumnEntity> dataSetColumnEntities = dataSetColumnService.columnListById(dataProcessEntity.getId());
        if(dataSetColumnEntities!=null && dataSetColumnEntities.size()>0) {
            for (DataSetColumnEntity dataSetColumnEntity : dataSetColumnEntities){
                columns.add(new HeardVO(dataSetColumnEntity.getColumnName(),dataSetColumnEntity.getColumnComment(),dataSetColumnEntity.getColumnType()));
            }
        }
        return columns;
    }
}
